<?php
declare (strict_types=1);

namespace app\user\logic\user;

use app\common\exception\LogicException;
use app\course\logic\coupon\Coupon as CourseCoupon;
use app\course\model\coupon\CouponOffline;
use app\course\model\coupon\CouponUser as CouponUserModel;
use app\school\logic\school\School;
use think\db\exception\DbException;
use think\Paginator;

/**
 * 账户卡券接口类
 * @method join(string $string, string $string1)
 */
class Coupon extends CouponUserModel
{

    /**
     * @throws DbException
     */
    public function list($type): Paginator
    {
        // 验证数据
        if (!in_array($type, ['usable', 'used', 'expired'])) throw new LogicException('参数错误');
        //
        $time = time();
        switch ($type) {
            case 'usable':    // 可用
                $couponSql = app(CourseCoupon::class)->whereNull('delete_time')->where('use_etime', '>=', $time)->field('id')->buildSql();
                $sql       = "(ticket_id is not null AND (end_time > $time OR end_time is null))";
                $mod       = $this->where('status', 0);
                break;
            case 'expired':    // 过期
                $couponSql = app(CourseCoupon::class)->whereNull('delete_time')->where('use_etime', '<', $time)->field('id')->buildSql();
                $sql       = "(ticket_id is not null AND end_time <= $time)";
                $mod       = $this->where('status', 0);
                break;
            case 'used':    // 已用
                $couponSql = app(CourseCoupon::class)->whereNull('delete_time')->field('id')->buildSql();
                $sql       = "(ticket_id is not null)";
                $mod       = $this->where('status', '<>', 0);
                break;

            default:
                $couponSql = app(CourseCoupon::class)->whereNull('delete_time')->field('id')->buildSql();
                $sql       = "(ticket_id is not null)";
                $mod       = $this;
                break;
        }
        $raw = "(coupon_id <> 0 AND coupon_id IN " . $couponSql . ") OR " . $sql;
        return $mod->field('coupon_id,code,mhm_id,ticket_id,end_time')->whereRaw($raw)->scope('mid')->hidden(['coupon'])->paginate($this->getListRows())->each(function ($item) {
            $item->mhm_sdn = app(School::class)->getSdn($item->mhm_id);
            if ($item->coupon_id) {
                $item->id           = $item->coupon_id;
                $coupon             = app(CourseCoupon::class)->findOrEmpty($item->coupon_id)->toArray();
                $item->coupon_type  = $coupon['coupon_type'];
                $item->school_name  = $coupon['school_name'];
                $item->course_id    = $coupon['course_id'];
                $item->course_title = $coupon['course_title'];
            }
            if ($item->ticket_id) {
                $coupon             = app(TicketCoupon::class)->findOrEmpty($item->ticket_id)->toArray();
                $item->school_name  = app(School::class)->getSchoolTitle($item->mhm_id);
                $item->coupon_type  = $coupon['coupon_type'];
                $item->course_id    = 0;
                $item->course_title = null;
            }
            $item->maxprice       = $coupon['maxprice'] ?? '0.00';
            $item->price          = $coupon['price'] ?? '0.00';
            $item->discount       = $coupon['discount'] ?? 0;
            $item->vip_date       = $coupon['vip_date'] ?? 0;
            $item->recharge_price = $coupon['recharge_price'] ?? '0.00';
            $item->course_type    = $coupon['course_type'] ?? null;
            $item->use_etime      = $coupon['use_etime'] ?? ($item->end_time ?? -1);
        });
    }

    public function exchange($param)
    {
        // 检查卡券
        $info = app(CouponOffline::class)->with(['coupon_can_exchange'])->where('offline_code', $param['code'])->findOrFail();
        // 已兑换
        if ($info->status == 1) throw new LogicException('此卡券已被兑换');
        // 已过领取时间、使用时间或已删除
        if ($info->coupon_can_exchange == null) throw new LogicException('此卡券已过期，不能兑换');
        // 生成数据
        $this->startTrans();
        try {
            $coupon_info         = app(CourseCoupon::class)->findOrFail($info->coupon_id);
            $data['user_id']     = request()->mid;
            $data['coupon_id']   = $info->coupon_id;
            $data['coupon_type'] = $coupon_info->coupon_type;
            $data['mhm_id']      = $coupon_info->mhm_id;
            $re1                 = $this::create($data);

            $info->code   = $re1->code;
            $info->status = 1;
            $re2          = $info->save();

            $coupon_info->receive_count += 1;
            $re3                        = $coupon_info->save();
            if ($re1->isEmpty() || !$re2 || !$re3) throw new LogicException('兑换失败');

            $this->commit();
        } catch (LogicException $e) {
            $this->rollback();
            throw new LogicException($e->getMessage());
        }

        return $this->alias('u')->join('coupon c', "c.id=u.coupon_id")->where('c.id', $info->coupon_id)->findOrFail();
    }
}
